package com.example.utils.util;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.util.List;

/**
 * Serializable工具(JDK)
 *
 * 	序列化是指把一个Java对象变成二进制内容，本质上就是一个byte[]数组。 为什么要把Java对象序列化呢？
 * 	因为序列化后可以把byte[]保存到文件中，或者把byte[]通过网络传输到远程，这样，就相当于把Java对象存储到文件或者通过网络传输出去了。
 * 	有序列化，就有反序列化，
 * 	即把一个二进制内容（也就是byte[]数组）变回Java对象。
 * 	有了反序列化，保存到文件中的byte[]数组又可以“变回”Java对象，或者从网络上读取byte[]并把它“变回”Java对象
 * 	也可用与 深拷贝
 */
public class SerializableUtil {

    private static final Logger LOGGER = LoggerFactory.getLogger(SerializableUtil.class);

    /**
     * jdk序列化
     * @param object
     * @return
     */
    public static byte[] serializable(Object object) {
        ByteArrayOutputStream baos = null;
        ObjectOutputStream oos = null;
        try {
            baos = new ByteArrayOutputStream();
            oos = new ObjectOutputStream(baos);
            oos.writeObject(object);
            return baos.toByteArray();
        } catch (IOException e) {
            LOGGER.error("serializable异常: " + e.getMessage());
            throw new RuntimeException("serializable异常: " + e.getMessage());
        } finally {
            try {
                if (oos != null) {
                    oos.close();
                }
                if (baos != null) {
                    baos.close();
                }
            } catch (IOException e) {
                LOGGER.error("serializable异常: " + e.getMessage());
                throw new RuntimeException("serializable异常: " + e.getMessage());
            }
        }
    }

    /**
     * jdk反序列化
     * @param bytes
     * @return
     */
    public static Object unserializable(byte[] bytes) {
        ByteArrayInputStream bais = null;
        ObjectInputStream ois = null;
        try {
            bais = new ByteArrayInputStream(bytes);
            ois = new ObjectInputStream(bais);
            return ois.readObject();
        } catch (Exception e) {
            throw new RuntimeException("unserializable异常: " + e.getMessage());
        } finally {
            try {
                if (ois != null) {
                    ois.close();
                }
                if (bais != null) {
                    bais.close();
                }
            } catch (IOException e) {
                LOGGER.error("unserializable异常: " + e.getMessage());
                throw new RuntimeException("unserializable异常: " + e.getMessage());
            }
        }
    }

    /**
      * @TODO       序列化深拷贝
      * @return     List<Object> objectList = deepCopy(srcList); // 使用方法
      * @Author 江
      * @Date 2022/10/2 18:10
      */
    public static <T> List<T> deepCopy(List<T> src) throws IOException, ClassNotFoundException {
        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
        ObjectOutputStream out = new ObjectOutputStream(byteOut);
        out.writeObject(src);
        ByteArrayInputStream byteIn = new ByteArrayInputStream(byteOut.toByteArray());
        ObjectInputStream in = new ObjectInputStream(byteIn);
        @SuppressWarnings("unchecked")
        List<T> dest = (List<T>) in.readObject();
        return dest;
    }

    /**
      * @TODO   clone方法解决深拷贝
     使用方法
    for (int i = 0; i < n; i++) {
        copy.add((A)src.get(i).clone());
    }
      * @return
      * @Author 江
      * @Date 2022/10/2 18:20
      */
    public class A implements Cloneable{
        public String name[];
        public A(){
            name = new String[2];
        }
        public Object clone(){
            A o = null;
            try {
                o = (A) super.clone();
            } catch (CloneNotSupportedException e) {
                e.printStackTrace();
            }
            return o;
        }

    }


}
